#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

// 线程的清理任务函数1
void cleanup_task(void *arg){
    printf("---计划清理（%p）堆空间 ---\n", arg);
}

void *task1(void *arg){
    int n = atoi((const char *)arg);
    int *ret = (int *)calloc(1, 4); // 从堆中申请功能

    // 注册清理函数
    pthread_cleanup_push(cleanup_task, ret);
    
    for(int i=1; i<=n;i++){
        *ret += i;
        if(*ret > 20 && *ret % 15 == 0){
            pthread_exit(ret);  // 提前退出
        }
    }

    // 执行清理任务
    pthread_cleanup_pop(1); // 弹出清理函数并执行

    return ret;
}

// ./a.out 10
int main(int argc, char const *argv[])
{
    if(argc != 2) return -1;
    pthread_t tid = 0; 
    // 将命令行传入数值，传递给子线程，子线程完成传入数值以内所有整数的和，
    // 当和大于20且是15的倍数时，则退出，并回传和的结果
    pthread_create(&tid, NULL, task1, (void *)argv[1]);
    if(tid <= 0){
        perror("pthread create");
        return -1;
    }
    int *ret = NULL;
    pthread_join(tid, (void **)&ret);
    printf("ret is %d\n", *ret);
    free(ret); // 将子线程创建的堆空间回收了(真回收)

    return 0;
}
